use crate::errors::MyError;
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
pub struct UserInit {
    pub user_name: String,
    pub pwd: String,
    pub code_source: String,
    pub client_id: String,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum Sex {
    Female = 0,
    Male = 1,
    NotSet = 2,
}

impl TryFrom<u8> for Sex {
    type Error = MyError;
    fn try_from(val: u8) -> Result<Sex, MyError> {
        match val {
            0 => Ok(Sex::Female),
            1 => Ok(Sex::Male),
            2 => Ok(Sex::NotSet),
            _ => Err(format!("Sex转换无效，来源:{}", val).into()),
        }
    }
}
impl From<Sex> for u8 {
    fn from(val: Sex) -> u8 {
        match val {
            Sex::Female => 0,
            Sex::Male => 1,
            Sex::NotSet => 2,
        }
    }
}
pub struct SqlSex(pub i32);

impl From<SqlSex> for Sex {
    fn from(val: SqlSex) -> Self {
        if let Ok(val1) = u8::try_from(val.0) {
            if let Ok(result) = Sex::try_from(val1) {
                return result;
            }
        }
        Sex::NotSet
    }
}

pub struct Sqlu8(pub Option<i32>);
impl From<Sqlu8> for Option<u8> {
    fn from(val: Sqlu8) -> Self {
        if let Some(val1) = val.0 {
            if let Ok(result) = u8::try_from(val1) {
                return Some(result);
            }
        }
        None
    }
}

pub struct Sqli32(pub Option<u8>);
impl From<Sqli32> for Option<i32> {
    fn from(val: Sqli32) -> Self {
        if let Some(val1) = val.0 {
            return Some(val1 as i32);
        }
        None
    }
}

impl From<Sex> for i32 {
    fn from(val: Sex) -> Self {
        match val {
            Sex::Female => 0,
            Sex::Male => 1,
            Sex::NotSet => 2,
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct User {
    pub user_name: String,
    /*
    pub sex: Sex,
    pub alias: Option<String>,
    pub birthday_year: Option<u8>,
    pub birthday_month: Option<u8>,
    pub birthday_day: Option<u8>,
    */
}

#[derive(Debug, Deserialize)]
pub struct LoginWithPwd {
    pub user_name: String,
    pub pwd: String,
    pub client_id: String,
    pub code_source: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct LoginResult {
    pub access_code: String,
    pub redirect_path: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Res<T> {
    pub data: T,
}

impl<T> Res<T> {
    pub fn new(val: T) -> Self {
        Self { data: val }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct GenCodeResult {
    pub code: String,
    pub img: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct CodeSource {
    pub code: String,
}
